/*
 * Copyright 2011 OpenWAF.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.openwaf.client.ui.widget;
import com.openwaf.client.event.HandlerRegistration;
import com.openwaf.client.event.dom.BlurHandler;
import com.openwaf.client.event.dom.ChangeHandler;
import com.openwaf.client.event.dom.ClickEvent;
import com.openwaf.client.event.dom.ClickHandler;
import com.openwaf.client.event.dom.ContextMenuHandler;
import com.openwaf.client.event.dom.DoubleClickHandler;
import com.openwaf.client.event.dom.KeyDownHandler;
import com.openwaf.client.event.dom.KeyPressHandler;
import com.openwaf.client.event.dom.KeyUpHandler;
import com.openwaf.client.event.dom.MouseDownHandler;
import com.openwaf.client.event.dom.MouseMoveHandler;
import com.openwaf.client.event.dom.MouseOutHandler;
import com.openwaf.client.event.dom.MouseOverHandler;
import com.openwaf.client.event.dom.MouseUpHandler;

import com.openwaf.client.core.Window;
import com.openwaf.client.dom.DivElement;
import com.openwaf.client.dom.Element;
import com.openwaf.client.dom.OListElement;
import com.openwaf.client.event.EventManager;
import com.openwaf.client.event.HandlerRegistration;
import com.openwaf.client.event.dom.MouseOverEvent;
import com.openwaf.client.event.dom.MouseOverHandler;
import com.openwaf.client.ui.UIControl;
import com.openwaf.client.ui.annotation.ViewElement;
import com.openwaf.client.ui.annotation.ViewMethod;
import com.openwaf.client.ui.annotation.ViewProperty;
import java.util.ArrayList;
import java.util.Iterator;

public class MenuItem extends UIControl implements Iterable<MenuItem> {



    private boolean root;
    private int index;
    private MenuBase menubar;
    private ArrayList<MenuItem> childs;
    @ViewElement
    private OListElement olChilds;
    @ViewElement
    private DivElement divMenu;
    @ViewElement
    private DivElement divImgSubMenu;
    @ViewElement
    private DivElement divText;

    public static String CCS_MENU_ITEM_NORMAL="waf-widget-menu-item";
    public static String CCS_MENU_ITEM_SELECTED="waf-widget-menu-item-selected";
    public static String CCS_MENU_BAR_ITEM_NORMAL="waf-widget-menu-bar-item";
    public static String CCS_MENU_BAR_ITEM_SELECTED="waf-widget-menu-bar-item-selected";
    


    public MenuItem() {
        root = false;
        childs = null;//initiated this only when needed
        menubar = null;
        divMenu.addMouseOverHandler(new MouseOverHandler() {
            public void onMouseOver(MouseOverEvent event) {
                show();
            }
        });

    }
    

    public MenuItem(String text) {
        this();
        setText(text);
    }

    @ViewProperty
    public final void setText(String text) {
        divText.setInnerHTML(text);
    }
    @ViewMethod
    public final void setText(Element element){
        divText.clearChilds();
        divText.appendChild(element);
    }

    public String getText() {
        return divText.getInnerHTML();
    }
    /*
     * Never call this
     * @Skip
     */

    public void setRoot(boolean value, MenuBase menubar) {
        root = value;
        if (value) {
            index = 0;
            this.menubar = menubar;
            updateIndex();
        }       
    }

    private boolean isRoot() {
        return root;
    }

    private void setMenuBar(MenuBar mb) {
        menubar = mb;
    }

    public MenuBase getMenuBar() {
        return menubar;
    }

    public int getIndex() {
        return index;
    }

    private void setIndex(int index) {
        this.index = index;
    }

    private void updateIndex() {
        if (childs == null) {
            return;
        }
        if(childs.isEmpty()) return;
        if((menubar!= null && menubar.isVertical()) || root==false){
            divImgSubMenu.getStyle().setDisplay("");
        }else{
            divImgSubMenu.getStyle().setDisplay("none");
        }
        if(menubar!=null && menubar.isHorizontal() && root==true){
            divMenu.setCssClassName(CCS_MENU_BAR_ITEM_NORMAL);
        }else{
            divMenu.setCssClassName(CCS_MENU_ITEM_NORMAL);
        }
        for (MenuItem item : childs) {
            item.index = index + 1;
            item.menubar = menubar;
            item.updateIndex();
        }
    }

    @ViewMethod
    public void addChild(MenuItem item) {
        if (childs == null) {
            beforeChildAdd();
        }
        childs.add(item);
        item.menubar = menubar;
        item.index = index + 1;
        item.updateIndex();
        olChilds.appendChild(item.getElement());
    }

    private void beforeChildAdd() {
        if (childs == null) {
            childs = new ArrayList<MenuItem>();
        }
        
    }

    public void addChild(int index, MenuItem item) {
        if (childs == null) {
            beforeChildAdd();
        }
        if (index < 0 || index > childs.size()) {
            throw new IndexOutOfBoundsException("Index out of range in Menuitem::addChildAt");
        }
        MenuItem exitem = childs.get(index);
        childs.add(index, item);
        item.menubar = menubar;
        item.index = index + 1;
        item.updateIndex();
        olChilds.insertBefore(item.getElement(), exitem.getElement());
    }

    public int getChildCount() {
        if (childs == null) {
            return 0;
        }
        return childs.size();
    }

    public boolean removeChild(MenuItem item) {
        if (childs == null) {
            throw new IndexOutOfBoundsException("Index out of range in Menuitem::removeChild");
        }
        if (!childs.contains(item)) {
            return false;
        }
        item.setMenuBar(null);
        olChilds.removeChild(item.getElement());
        return childs.remove(item);
    }

    public boolean removeChild(int index) {
        if (childs == null) {
            throw new IndexOutOfBoundsException("Index out of range in Menuitem::removeChildAt");
        }
        if (index < 0 || index > childs.size()) {
            throw new IndexOutOfBoundsException("Index out of range in Menuitem::removeChildAt");
        }
        MenuItem item = childs.get(index);
        olChilds.removeChild(item.getElement());
        item.setMenuBar(null);
        return childs.remove(index) != null;
    }

    public void hide() {
        if(menubar.isHorizontal() && root==true){
            divMenu.setCssClassName(CCS_MENU_BAR_ITEM_NORMAL);
        }else{
            divMenu.setCssClassName(CCS_MENU_ITEM_NORMAL);
        }
        olChilds.getStyle().setDisplay("none");
    }

    public void show() {
        if (isRoot()) {
            if (menubar.isVertical()) {
                olChilds.getStyle().setMarginLeft("" + (getElement().getOffsetWidth()) + "px");
            } else {
                olChilds.getStyle().setMarginTop("" + menubar.getElement().getOffsetHeight() + "px");
            }
        } else {
            olChilds.getStyle().setMarginLeft("" + getElement().getOffsetWidth() + "px");
        }
        menubar.addMenuToHide(this);
        if(menubar.isHorizontal() && root==true){
            divMenu.setCssClassName(CCS_MENU_BAR_ITEM_SELECTED);
        }else{
            divMenu.setCssClassName(CCS_MENU_ITEM_SELECTED);
        }
        if(childs!=null && childs.isEmpty()==false){
            olChilds.getStyle().setDisplay("");
        }
    }
    public Iterator<MenuItem> iterator() {
        if(childs==null){
            beforeChildAdd();
        }
        return childs.iterator();
    }

    @Override
    public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
        return divText.addKeyDownHandler(handler);
    }

    @Override
    public HandlerRegistration addKeyUpHandler(KeyUpHandler handler) {
        return divText.addKeyUpHandler(handler);
    }

    @Override
    public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) {
        return divText.addKeyPressHandler(handler);
    }

    @Override
    public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) {
        return divText.addMouseDownHandler(handler);
    }

    @Override
    public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler) {
        return divText.addMouseMoveHandler(handler);
    }

    @Override
    public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
        return divText.addMouseOutHandler(handler);
    }

    @Override
    public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) {
        return divText.addMouseOverHandler(handler);
    }

    @Override
    public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) {
        return divText.addMouseUpHandler(handler);
    }

    @Override
    public HandlerRegistration addClickHandler(ClickHandler handler) {
        return divText.addClickHandler(handler);
    }

    @Override
    public HandlerRegistration addContextMenuHandler(ContextMenuHandler handler) {
        return divText.addContextMenuHandler(handler);
    }

    @Override
    public HandlerRegistration addDoubleClickHandler(DoubleClickHandler handler) {
        return divText.addDoubleClickHandler(handler);
    }
}
